//
//  SimpleGCD_VC.m
//  thread
//
//  Created by 关旭 on 2019/3/8.
//  Copyright © 2019 guanxu. All rights reserved.
//

#import "SimpleGCD_VC.h"

@interface SimpleGCD_VC () {
    UIImageView *showImage;
    UILabel *imageState;
}

@end

@implementation SimpleGCD_VC

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    
//    [self initView];
//    [self loadImage];
    
    //    [self syncConcurrent];//阻塞主线程
//    [self asyncConcurrent];//不阻塞主线程
//    [self syncSerial];//阻塞主线程
//    [self asyncSerial];//不阻塞主线程
    
//    [self syncMain];//程序死锁
    // 使用 NSThread 的 detachNewThreadSelector 方法会创建线程，并自动启动线程执行selector 任务
//    [NSThread detachNewThreadSelector:@selector(syncMain) toTarget:self withObject:nil];
    
//    [self asyncMain];//不阻塞线程
    [self after];
}
- (void)viewDidAppear:(BOOL)animated {


}
#pragma mark --------------------GCD一次性代码
- (void)once {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
//        只执行一次的代码
    });
}
#pragma mark --------------------GCD 延时方法：dispatch_after
- (void)after {
    NSLog(@"currentThread---%@",[NSThread currentThread]);  // 打印当前线程
    NSLog(@"asyncMain---begin");
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //        两秒后异步追加任务到主队列，并开始执行
        NSLog(@"after -------%@",[NSThread currentThread]);
    });
}
#pragma mark ------------------------GCD 基本使用(六种不同的组合)
#pragma mark -----------------------异步执行主队列：在主线程中串行执行任务
- (void)asyncMain {
    NSLog(@"mainThread---%@",[NSThread currentThread]); // 打印当前线程
    NSLog(@"asyncSerial---begin");
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_async(queue, ^{
        for(int i=0;i<2;i++){//        任务1
            [NSThread sleepForTimeInterval:2];//模拟耗时操作
            NSLog(@"1-------%@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        //        任务2
        for(int i=0;i<2;i++){
            [NSThread sleepForTimeInterval:2];
            NSLog(@"2-------%@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        //        任务3
        for(int i=0;i<2;i++){
            [NSThread sleepForTimeInterval:2];
            NSLog(@"3-------%@",[NSThread currentThread]);
        }
    });
    NSLog(@"main---end");
}

#pragma mark -----------------------同步执行主队列
//在主线程中使用 同步执行主队列，程序会出现死锁
- (void)syncMain {
    NSLog(@"mainThread---%@",[NSThread currentThread]); // 打印当前线程
    NSLog(@"syncSerial---begin");
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_sync(queue, ^{
        for(int i=0;i<2;i++){//        任务1
            [NSThread sleepForTimeInterval:2];//模拟耗时操作
            NSLog(@"1-------%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        //        任务2
        for(int i=0;i<2;i++){
            [NSThread sleepForTimeInterval:2];
            NSLog(@"2-------%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        //        任务3
        for(int i=0;i<2;i++){
            [NSThread sleepForTimeInterval:2];
            NSLog(@"3-------%@",[NSThread currentThread]);
        }
    });
    NSLog(@"main---end");
}



#pragma mark -----------------------异步执行串行对类：开启新线程，在当前线程下串行执行任务，任务不做等待
- (void)asyncSerial {
    NSLog(@"serialThread---%@",[NSThread currentThread]); // 打印当前线程
    NSLog(@"asyncSerial---begin");
    dispatch_queue_t queue = dispatch_queue_create("serial.queue.test", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        //        任务1
        for(int i=0;i<2;i++){
            [NSThread sleepForTimeInterval:2];//模拟耗时操作
            NSLog(@"1-------%@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        //        任务2
        for(int i=0;i<2;i++){
            [NSThread sleepForTimeInterval:2];
            NSLog(@"2-------%@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        //        任务3
        for(int i=0;i<2;i++){
            [NSThread sleepForTimeInterval:2];
            NSLog(@"3-------%@",[NSThread currentThread]);
        }
    });
    NSLog(@"asyncSerial---end");
}

#pragma mark -----------------------同步执行串行对类：不开启新线程，在当前线程下串行执行任务
- (void)syncSerial {
    NSLog(@"serialThread---%@",[NSThread currentThread]); // 打印当前线程
    NSLog(@"syncSerial---begin");
    dispatch_queue_t queue = dispatch_queue_create("serial.queue.test", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(queue, ^{
        //        任务1
        for(int i=0;i<2;i++){
            [NSThread sleepForTimeInterval:2];//模拟耗时操作
            NSLog(@"1-------%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        //        任务2
        for(int i=0;i<2;i++){
            [NSThread sleepForTimeInterval:2];
            NSLog(@"2-------%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        //        任务3
        for(int i=0;i<2;i++){
            [NSThread sleepForTimeInterval:2];
            NSLog(@"3-------%@",[NSThread currentThread]);
        }
    });
    NSLog(@"syncSerial---end");
}



#pragma mark -------------------------异步执行并发队列：开启多个线程，任务交替(同时)执行
- (void)asyncConcurrent {
    NSLog(@"currentThread---%@",[NSThread currentThread]); // 打印当前线程
    NSLog(@"asyncConcurrent---begin");
    dispatch_queue_t queue = dispatch_queue_create("concurrent.queue.test", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        //        任务1
        for(int i=0;i<2;i++){
            [NSThread sleepForTimeInterval:2];//模拟耗时操作
            NSLog(@"1-------%@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        //        任务2
        for(int i=0;i<2;i++){
            [NSThread sleepForTimeInterval:2];
            NSLog(@"2-------%@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        //        任务3
        for(int i=0;i<2;i++){
            [NSThread sleepForTimeInterval:2];
            NSLog(@"3-------%@",[NSThread currentThread]);
        }
    });
    NSLog(@"asyncConcurrent---end");
}
#pragma mark ------------------------同步执行并发队列：不开启新线程，执行完一个任务在执行下一个任务，因为只有一个线程
- (void)syncConcurrent {
    NSLog(@"currentThread---%@",[NSThread currentThread]);  // 打印当前线程
    NSLog(@"syncConcurrent---begin");
    dispatch_queue_t queue = dispatch_queue_create("concurrent.queue.test", DISPATCH_QUEUE_CONCURRENT);
    dispatch_sync(queue, ^{
//        任务1
        for(int i=0;i<2;i++){
            [NSThread sleepForTimeInterval:2];//模拟耗时操作
            NSLog(@"1-------%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        //        任务2
        for(int i=0;i<2;i++){
            [NSThread sleepForTimeInterval:2];
            NSLog(@"2-------%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        //        任务3
        for(int i=0;i<2;i++){
            [NSThread sleepForTimeInterval:2];
            NSLog(@"3-------%@",[NSThread currentThread]);
        }
    });
    NSLog(@"syncConcurrent---end");
}






- (void)loadImage {
    //获取一个优先级默认的全局并发队列，并以异步的方式提交任务执行
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //下载图片
        UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://i1.bvimg.com/679654/2017809566581a8b.jpg"]]];
        //获取主队列，在主线程中更新UI，并以异步方式提交任务
        dispatch_async(dispatch_get_main_queue(), ^{
            [self->imageState removeFromSuperview];
            self->imageState = nil;
            self->showImage.image = image;
        });
    });
}
- (void)initView {
    UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 200, 200)];
    imageView.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:imageView];
    imageView.center = self.view.center;
    
    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 200, 40)];
    label.textColor = [UIColor blackColor];
    label.backgroundColor = [UIColor clearColor];
    [self.view addSubview:label];
    label.center = self.view.center;
    label.text = @"请稍候";
    label.textAlignment = NSTextAlignmentCenter;
    
    
    showImage = imageView;
    imageState = label;
}

#pragma mark ----------------------常用 API 介绍
- (void)methodsIntroduce {
//    串行队列的创建方法
    dispatch_queue_t serialQueue = dispatch_queue_create("seriql.queue.test", DISPATCH_QUEUE_SERIAL);
//    并发队列的创建方法
    dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrent.queue.test", DISPATCH_QUEUE_CONCURRENT);
    
//    获取主队列 特殊的串行队列
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    
//    全局并发队列获取
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
//    任务的创建方法
//    同步执行任务创建方法
    dispatch_sync(mainQueue, ^{
//        同步执行任务代码
    });
//    异步执行任务创建方法
    dispatch_async(mainQueue, ^{
//        异步执行任务代码
    });
    
    
    
    
}


/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
